---
slug: /api/constructor
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Constructors

Every Dagger module has a constructor. The default one is generated automatically and has no arguments.

It's possible to write a custom constructor. The mechanism to do this is SDK-specific.

This is a simple way to accept module-wide configuration, or just to set a few attributes without having to create setter functions for them.

## Simple constructor

The default constructor for a module can be overridden by registering a custom constructor. Its parameters are available as flags in the `dagger call` command directly.

:::important
Dagger modules have only one constructors. Constructors of [custom types](./custom-types.mdx) are not registered; they are constructed by the function that [chains](./index.mdx#chaining) them.
:::

Here is an example module with a custom constructor:

<Tabs groupId="language">
<TabItem value="Go">

```go file=./snippets/constructors/go/simple/main.go
```

</TabItem>
<TabItem value="Python">

```python file=./snippets/constructors/python/simple/main.py
```

:::info
In the Python SDK, the [`@dagger.object_type`](https://dagger-io.readthedocs.io/en/latest/module.html#dagger.object_type) decorator wraps [`@dataclasses.dataclass`](https://docs.python.org/3/library/dataclasses.html), which means that an `__init__()` method is automatically generated, with parameters that match the declared class attributes.
:::

The code listing above is an example of an object that has typed attributes.

If a constructor argument needs an asynchronous call to set the default value, it's
possible to replace the default constructor function from `__init__()` to
a factory class method named `create`, as in the following code listing:

:::warning
This factory class method must be named `create`.
:::

```python file=./snippets/constructors/python/async/main.py
```
</TabItem>
<TabItem value="TypeScript">

```typescript file=./snippets/constructors/typescript/simple/index.ts
```

</TabItem>
<TabItem value="PHP">

```php file=./snippets/constructors/php/simple/src/MyModule.php
```

:::info
In the PHP SDK the constructor must be the [magic method `__construct`](https://www.php.net/manual/en/language.oop5.decon.php#object.construct).
As with any method, only public methods with the `#[DaggerFunction]` attribute will be registered with Dagger.
:::
</TabItem>
</Tabs>

Here is an example call for this Dagger Function:

```shell
dagger call --name=Foo message
```

The result will be:

```shell
Hello, Foo!
```

:::important
If you plan to use constructor fields in other module functions, ensure that they are declared as public (in Go and TypeScript). This is because Dagger stores fields using serialization and private fields are omitted during the serialization process. As a result, if a field is not declared as public, calling methods that use it will produce unexpected results.
:::

## Default values for complex types

Constructors can be passed both simple and complex types (such as `Container`, `Directory`, `Service` etc.) as arguments. Default values can be assigned in both cases.

Here is an example of a Dagger module with a default constructor argument of type `Container`:

<Tabs groupId="language">
<TabItem value="Go">

```go file=./snippets/constructors/go/default-object/main.go
```

</TabItem>
<TabItem value="Python">

```python file=./snippets/constructors/python/default-object/main.py
```

For default values that are more complex, dynamic or just [mutable](https://docs.python.org/3/library/dataclasses.html#mutable-default-values),
use a [factory function](https://docs.python.org/3/library/dataclasses.html#default-factory-functions) without arguments in
[dataclasses.field(default_factory=...)](https://docs.python.org/3/library/dataclasses.html#dataclasses.field):

```python file=./snippets/constructors/python/factory/main.py
```

</TabItem>
<TabItem value="TypeScript">

```typescript file=./snippets/constructors/typescript/default-object/index.ts
```

This default value can also be assigned directly in the field:

```typescript file=./snippets/constructors/typescript/default-object-in-field/index.ts
```

:::important
When assigning default values to complex types in TypeScript, it is necessary to use the `??` notation for this assignment. It is not possible to use the classic TypeScript notation for default arguments because the argument in this case is not a TypeScript primitive.
:::

</TabItem>
<TabItem value="PHP">

```php file=./snippets/constructors/php/default-object/src/MyModule.php
```

</TabItem>
</Tabs>

It is necessary to explicitly declare the type even when a default value is assigned, so that the Dagger SDK can extend the GraphQL schema correctly.

Here is an example call for this Dagger Function:

```shell
dagger call version
```

The result will be:

```shell
VERSION_ID=3.14.0
```
